home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 21 / Cream of the Crop 21 (Terry Blount) (October 1996).iso / os2 / nortutil.zip / src / Ddate / dsub.c < prev   
C/C++ Source or Header  |  1996-08-27  |  9KB  |  342 lines

  1. /* $ DVCS ID: $jer|,523/lhos,KYTP!41023161\b"?" <<= DO NOT DELETE! */
  2.  
  3. /* ddate.c .. converts boring normal dates to fun Discordian Date -><-
  4.    original incarnation written the 65th day of The Aftermath in the 
  5.    Year of Our Lady of Discord 3157 by Druel the Chaotic aka Jeremy Johnson 
  6.    aka mpython@gnu.ai.mit.edu.
  7.    Majorly hacked, extended and bogotified/debogotified on 
  8.    Sweetmorn, Bureaucracy 42, 3161 YOLD, by Lee H:. O:. Smith, KYTP, 
  9.    aka Andrew Bulhak, aka acb@zikzak.net
  10.  
  11.    and I'm not responsible if this program messes anything up (except your 
  12.    mind, I'm responsible for that) (and that goes for me as well --lhos)
  13. */
  14.  
  15.  
  16. /* configuration options  VVVVV   READ THIS!!! */
  17.  
  18. /* If you wish ddate(1) to print the date in the same format as Druel's 
  19.  * original ddate when called in immediate mode, define OLD_IMMEDIATE_FMT 
  20.  */
  21.  
  22. #define OLD_IMMEDIATE_FMT
  23.  
  24. /* If you wish to use the US format for aneristic dates (m-d-y), as opposed to
  25.  * the Commonwealth format, define US_FORMAT.
  26.  */
  27.  
  28. /* #define US_FORMAT */
  29.  
  30. /* If you are ideologically, theologically or otherwise opposed to the 
  31.  * Church of the SubGenius and do not wish your copy of ddate(1) to contain
  32.  * code for counting down to X-Day, undefine PRAISE_BOB */
  33.  
  34. #define PRAISE_BOB 13013
  35.  
  36. #include <time.h>
  37. #include <string.h>
  38. #include <stdio.h>
  39.  
  40. #ifndef __GNUC__
  41. #define inline /* foo */
  42. #endif
  43.  
  44. /* string constants */
  45.  
  46. char *day_long[5] = { 
  47.     "Sweetmorn", "Boomtime", "Pungenday", "Prickle-Prickle", "Setting Orange"
  48. };
  49.  
  50. char *day_short[5] = {"SM","BT","PD","PP","SO"};
  51.  
  52. char *season_long[5] = { 
  53.     "Chaos", "Discord", "Confusion", "Bureaucracy", "The Aftermath"
  54. };
  55.  
  56. char *season_short[5] = {"Chs", "Dsc", "Cfn", "Bcy", "Afm"};
  57.  
  58. char *holyday[5][2] = { 
  59.     "Mungday", "Chaoflux",
  60.     "Mojoday", "Discoflux",
  61.     "Syaday",  "Confuflux",
  62.     "Zaraday", "Bureflux",
  63.     "Maladay", "Afflux"
  64. };
  65.  
  66. struct disc_time {
  67.     int season; /* 0-4 */
  68.     int day; /* 0-72 */
  69.     int yday; /* 0-365 */
  70.     int year; /* 3066- */
  71. };
  72.  
  73. char *excl[] = {
  74.     "Hail Eris!", "All Hail Discordia!", "Kallisti!", "Fnord.", "Or not.",
  75.     "Wibble.", "Pzat!", "P'tang!", "Frink!",
  76. #ifdef PRAISE_BOB
  77.     "Slack!", "Praise \"Bob\"!", "Or kill me.",
  78. #endif /* PRAISE_BOB */
  79.     /* randomness, from the Net and other places. Feel free to add (after
  80.        checking with the relevant authorities, of course). */
  81.     "Grudnuk demand sustenance!", "Keep the Lasagna flying!", 
  82.     "Quack!", "Are we not Y.E.T.I.?",
  83.     ""
  84. };
  85.  
  86. char default_fmt[] = "%{%A, %B %d%}, %Y YOLD";
  87. char *default_immediate_fmt=
  88. #ifdef OLD_IMMEDIATE_FMT
  89. "Today is %{%A, the %e day of %B%} in the YOLD %Y %n%X days til X-Day %t%.%n%N%nCelebrate %H"
  90. #else
  91. default_fmt
  92. #endif
  93. ;
  94.  
  95. #define DY(y) (y+1166)
  96.  
  97. inline char *ending(int i) { return (i%10==1)?"st":(i%10==2?"nd":(i%10==3?"rd":"th"));};
  98. inline int leapp(int i) { return (!(DY(i)%4))&&((DY(i)%100)||(!(DY(i)%400)));};
  99.  
  100. void print(struct disc_time,char **); /* old */
  101. void format(char *buf, const char* fmt, struct disc_time dt);
  102. /* select a random string */
  103. inline char *sel(char **strings, int num) {return(strings[random()%num]); }; 
  104. /* read a fortune file */
  105. int load_fortunes(char *fn, char *delim, char** result);
  106.  
  107. struct disc_time convert(int,int);
  108. struct disc_time makeday(int,int,int);
  109.  
  110. main (int argc, char *argv[]) 
  111. {
  112.     long t;
  113.     struct tm *eris;
  114.     int bob,raw;
  115.     struct disc_time hastur;
  116.     char schwa[23*17], *fnord=0;
  117.     int pi;
  118.  
  119.     srandom(time(NULL));
  120.     /* do args here */
  121.     for(pi=1; pi<argc; pi++) {
  122.     switch(argv[pi][0]) {
  123.     case '+': fnord=argv[pi]+1; break;
  124.     case '-': 
  125.         switch(argv[pi][1]) {
  126.         default: goto usage;
  127.         }
  128.     default: goto thud;
  129.     }
  130.     }
  131.  
  132.   thud:
  133.     if (argc-pi==3){ 
  134.     int moe=atoi(argv[pi]), larry=atoi(argv[pi+1]), curly=atoi(argv[pi+2]);
  135.     hastur=makeday(
  136. #ifdef US_FORMAT
  137.         moe,larry,
  138. #else
  139.         larry,moe,
  140. #endif
  141.         curly);
  142.     fnord=fnord?fnord:default_fmt;
  143.     } else if (argc!=pi) { 
  144.       usage:
  145.     fprintf(stderr,"usage: %s [+format] [day month year]\n", argv[0]);
  146.     exit(1);
  147.     } else {
  148.     t= time(NULL);
  149.     eris=localtime(&t);
  150.     bob=eris->tm_yday; /* days since Jan 1. */
  151.     raw=eris->tm_year; /* years since 1980 */
  152.     hastur=convert(bob,raw);
  153.     fnord=fnord?fnord:default_immediate_fmt;
  154.     }
  155.     format(schwa, fnord, hastur);
  156.     printf("%s\n", schwa);
  157.     return 0;
  158. }
  159.  
  160. void format(char *buf, const char* fmt, struct disc_time dt)
  161. {
  162.     int tib_start=-1, tib_end=0;
  163.     int i, fmtlen=strlen(fmt);
  164.     char *bufptr=buf;
  165.  
  166. /*    fprintf(stderr, "format(%p, \"%s\", dt)\n", buf, fmt);*/
  167.  
  168.     /* first, find extents of St. Tib's Day area, if defined */
  169.     for(i=0; i<fmtlen; i++) {
  170.     if(fmt[i]=='%') {
  171.         switch(fmt[i+1]) {
  172.         case 'A':
  173.         case 'a':
  174.         case 'd':
  175.         case 'e':
  176.         if(tib_start>0)        tib_end=i+1;
  177.         else            tib_start=i;
  178.         break;
  179.         case '{': tib_start=i; break;
  180.         case '}': tib_end=i+1; break;
  181.         }
  182.     }
  183.     }
  184.  
  185.     /* now do the formatting */
  186.     buf[0]=0;
  187.  
  188.     for(i=0; i<fmtlen; i++) {
  189.     if((i==tib_start) && (dt.day==-1)) {
  190.         /* handle St. Tib's Day */
  191.         strcpy(bufptr, "St. Tib's Day"); bufptr += 13;
  192.         i=tib_end;
  193.     } else {
  194.         if(fmt[i]=='%') {
  195.         char *wibble=0, snarf[23];
  196.         switch(fmt[++i]) {
  197.         case 'A': wibble=day_long[dt.yday%5]; break;
  198.         case 'a': wibble=day_short[dt.yday%5]; break;
  199.         case 'B': wibble=season_long[dt.season]; break;
  200.         case 'b': wibble=season_short[dt.season]; break;
  201.         case 'd': sprintf(snarf, "%d", dt.day+1); wibble=snarf; break;
  202.         case 'e': sprintf(snarf, "%d%s", dt.day+1, ending(dt.day+1)); 
  203.             wibble=snarf; break;
  204.         case 'H': if(dt.day==4||dt.day==49)
  205.             wibble=holyday[dt.season][dt.day==49]; break;
  206.         case 'N': if(dt.day!=4&&dt.day!=49) goto eschaton; break;
  207.         case 'n': *(bufptr++)='\n'; break;
  208.         case 't': *(bufptr++)='\t'; break;
  209.             
  210.         case 'Y': sprintf(snarf, "%d", dt.year); wibble=snarf; break;
  211.         case '.': wibble=sel(excl, sizeof(excl)/sizeof(excl[0]));
  212.             break;
  213. #ifdef PRAISE_BOB
  214.         case 'X': sprintf(snarf, "%d", 
  215.                   xday_countdown(dt.yday, dt.year));
  216.                   wibble = snarf; break;
  217. #endif /* PRAISE_BOB */
  218.         }
  219.         if(wibble) {
  220. /*            fprintf(stderr, "wibble = (%s)\n", wibble);*/
  221.             strcpy(bufptr, wibble); bufptr+=strlen(wibble);
  222.         }
  223.         } else {
  224.         *(bufptr++) = fmt[i];
  225.         }
  226.     }
  227.     }
  228.   eschaton:
  229.     *(bufptr)=0;
  230. }
  231.  
  232. struct disc_time makeday(int imonth,int iday,int iyear) /*i for input */
  233.     struct disc_time funkychickens;
  234.     
  235.     int cal[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
  236.     int dayspast=0;
  237.     
  238.     imonth--;
  239.     funkychickens.year= iyear+1166;
  240.     while(imonth>0) { dayspast+=cal[--imonth]; }
  241.     funkychickens.day=dayspast+iday-1;
  242.     funkychickens.season=0;
  243.     if((funkychickens.year%4)==2) {
  244.     if (funkychickens.day==59)  funkychickens.day=-1;
  245.     }
  246.     funkychickens.yday=funkychickens.day;
  247. /*               note: EQUAL SIGN...hopefully that fixes it */
  248.     while(funkychickens.day>=73) {
  249.     funkychickens.season++;
  250.     funkychickens.day-=73;
  251.     }
  252.     return funkychickens;
  253. }
  254.  
  255. #if 0
  256. char *ending(int num)
  257. {  
  258.  int temp;
  259.  char *funkychickens;
  260.  
  261.  funkychickens=(char *)malloc(sizeof(char)*3);
  262.  
  263.   temp=num%10; /* get 0-9 */  
  264.   switch (temp)
  265.   { case 1:
  266.       strcpy(funkychickens,"st");
  267.       break;
  268.     case 2:
  269.       strcpy(funkychickens,"nd");
  270.       break;
  271.     case 3:
  272.       strcpy(funkychickens,"rd");
  273.       break;
  274.     default:
  275.       strcpy(funkychickens,"th");
  276.     }
  277.  return funkychickens;
  278. }
  279. #endif
  280.  
  281. struct disc_time convert(int nday, int nyear)
  282. {  struct disc_time funkychickens;
  283.    
  284.    funkychickens.year = nyear+3066;
  285.    funkychickens.day=nday;
  286.    funkychickens.season=0;
  287.    if ((funkychickens.year%4)==2)
  288.      {if (funkychickens.day==59)
  289.     funkychickens.day=-1;
  290.      else if (funkychickens.day >59)
  291.        funkychickens.day-=1;
  292.     }
  293.    funkychickens.yday=funkychickens.day;
  294.    while (funkychickens.day>=73)
  295.      { funkychickens.season++;
  296.        funkychickens.day-=73;
  297.      }
  298.    return funkychickens;
  299.   
  300.  }
  301.  
  302.  
  303. #ifdef PRAISE_B